package com.example.meitu.api.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.meitu.api.common.UserLoginContextHolder;
import com.example.meitu.api.domain.*;
import com.example.meitu.api.dto.FugaituCardDTO;
import com.example.meitu.api.dto.FugaituCardMediaDTO;
import com.example.meitu.api.dto.SaveUserMediaTypeForm;
import com.example.meitu.api.dto.UserMediaTypeDTO;
import com.example.meitu.api.service.*;
import com.example.meitu.api.dao.MediaTypeMapper;
import com.example.meitu.api.util.SmsUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author 蔡超
* @description 针对表【mt_media_type(媒体类别表)】的数据库操作Service实现
* @createDate 2024-06-27 23:01:54
*/
@Service
public class MediaTypeServiceImpl extends ServiceImpl<MediaTypeMapper, MediaType>
    implements MediaTypeService{

    @Value("${sms.frequency}")
    private Long frequency;

    @Resource
    private AddMediaTypeService addMediaTypeService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private UserMediaTypeService userMediaTypeService;

    @Resource
    private UserMediaTypeHistoryService userMediaTypeHistoryService;

    @Resource
    private SmsUtils smsUtils;

    @Override
    public List<MediaType> listByTypeAndPid(String type, Integer pId, Integer userId, Integer brandId) {
        LambdaQueryWrapper<MediaType> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(MediaType::getType, type);
        lambdaQueryWrapper.eq(MediaType::getPid, pId);
        lambdaQueryWrapper.eq(MediaType::getScope, '0');
        lambdaQueryWrapper.eq(MediaType::getDelFlag, '0');
        lambdaQueryWrapper.orderByAsc(MediaType::getSort);
        //TODO 权限校验
        Collection<Integer> permissionList = getpermissionList(type, brandId, userId);
        if (CollectionUtils.isNotEmpty(permissionList)) {
            lambdaQueryWrapper.in(MediaType::getId, permissionList);
        }
        List<MediaType> list = list(lambdaQueryWrapper);
        return list;
    }

    @Override
    @Transactional
    public void saveUserMediaType(SaveUserMediaTypeForm saveUserMediaTypeForm) {
        int userId = UserLoginContextHolder.get().getUserId();

        // 保存自定义类别
        String[] topMediaTypeIds = saveUserMediaTypeForm.getTopMediaTypeIds();
        String[] subMediaTypeIds = saveUserMediaTypeForm.getSubMediaTypeIds();
        if ((topMediaTypeIds !=null && topMediaTypeIds.length > 0) || (subMediaTypeIds !=null && subMediaTypeIds.length > 0)) {
            //查询跟之前的是否一致，如果一致就不修改，不一致，先把历史的保存一下，再更新用户列表表
            LambdaQueryWrapper<UserMediaType> searchWrapper = new LambdaQueryWrapper<>();
            searchWrapper.eq(UserMediaType::getUserId, userId);
            searchWrapper.eq(UserMediaType::getBrandId, saveUserMediaTypeForm.getBrandId());
            UserMediaType userMediaType = userMediaTypeService.getOne(searchWrapper);
            if (userMediaType == null) {
                LambdaQueryWrapper<UserMediaType> userMediaTypeWrapperDefault = new LambdaQueryWrapper<>();
                userMediaTypeWrapperDefault.eq(UserMediaType::getUserId, 0);
                userMediaTypeWrapperDefault.eq(UserMediaType::getBrandId, 0);
                userMediaTypeWrapperDefault.eq(UserMediaType::getDelFlag, '0');
                List<UserMediaType> list = userMediaTypeService.list(userMediaTypeWrapperDefault);
                UserMediaType defaultUserMediaType = list.get(0);

                userMediaType = new UserMediaType();
                userMediaType.setUserId(userId);
                userMediaType.setBrandId(saveUserMediaTypeForm.getBrandId());
                userMediaType.setTopMediaTypeId(StringUtils.join(topMediaTypeIds,","));
                userMediaType.setSubdivideMediaTypeId(StringUtils.join(subMediaTypeIds,","));
                userMediaType.setPermissionMediaType(defaultUserMediaType.getPermissionMediaType());
                userMediaType.setPermissionMediaTypeDalei(defaultUserMediaType.getPermissionMediaTypeDalei());
                userMediaType.setCreateBy(String.valueOf(userId));
                userMediaType.setCreateTime(new Date());
                userMediaTypeService.save(userMediaType);
            } else {
                //判断本次设置跟之前的设置是否一致，如果不一致则更新，然后保存历史，如果一致，只更新更新时间和更新人即可
                boolean isSame = isSame(saveUserMediaTypeForm, userMediaType);
                if (isSame) {
                    userMediaType.setUpdateBy(String.valueOf(userId));
                    userMediaType.setUpdateTime(new Date());
                    userMediaTypeService.updateById(userMediaType);
                } else {

                    UserMediaTypeHistory userMediaTypeHistory = new UserMediaTypeHistory();
                    userMediaTypeHistory.setUserId(userId);
                    userMediaTypeHistory.setBrandId(userMediaType.getBrandId());
                    userMediaTypeHistory.setTopMediaTypeId(userMediaType.getTopMediaTypeId());
                    userMediaTypeHistory.setSubdivideMediaTypeId(userMediaType.getSubdivideMediaTypeId());
                    userMediaTypeHistory.setCreateBy(String.valueOf(userId));
                    userMediaTypeHistory.setCreateTime(new Date());
                    userMediaTypeHistoryService.save(userMediaTypeHistory);

                    userMediaType.setTopMediaTypeId(StringUtils.join(saveUserMediaTypeForm.getTopMediaTypeIds(),","));
                    userMediaType.setSubdivideMediaTypeId(StringUtils.join(saveUserMediaTypeForm.getSubMediaTypeIds(),","));
                    userMediaType.setUpdateBy(String.valueOf(userId));
                    userMediaType.setUpdateTime(new Date());
                    userMediaTypeService.updateById(userMediaType);
                }
            }

        }


        if (saveUserMediaTypeForm.getNewType() != null && saveUserMediaTypeForm.getNewType().length > 0) {
            String newType = Arrays.toString(saveUserMediaTypeForm.getNewType());
            // 保存 用户新增媒体记录表
            AddMediaType addMediaType = new AddMediaType();
            addMediaType.setUserId(userId);
            addMediaType.setNewtype(newType);
            addMediaType.setBrandId(saveUserMediaTypeForm.getBrandId());
            addMediaType.setBrandName(saveUserMediaTypeForm.getBrandName());
            addMediaType.setCreateBy(String.valueOf(userId));
            addMediaType.setCreateTime(new Date());
            addMediaTypeService.save(addMediaType);

            // 新增分类发短信(异步)
            // 同一用户，同一品牌，1天之内，只能增加10次
            // 先注释，后期可能会改成发短信
//            String smsKey = "sms:frequency:" + userId + ":" + saveUserMediaTypeForm.getBrandId();
//            long size = redisTemplate.opsForList().size(smsKey);
//            if (size >= frequency) {
//                return;
//            }
//
//            SimpleDateFormat format = new SimpleDateFormat("MM-dd");
//            String date = format.format(new Date());
//            String name = UserLoginContextHolder.get().getName();
//            String brandName = saveUserMediaTypeForm.getBrandName();
//            String msg = String.format("%s %s 用户 %s 申请增加媒体分类：%s", date, brandName, name, newType);
//            String phone  = stringRedisTemplate.opsForValue().get("add_media_type_contacts");
//            smsUtils.sendMsg(phone, msg);
//            redisTemplate.opsForList().leftPush(smsKey, newType);
        }

    }

    private boolean isSame(SaveUserMediaTypeForm saveUserMediaTypeForm, UserMediaType userMediaType) {
        String[] subMediaIds = saveUserMediaTypeForm.getSubMediaTypeIds();
        String[] topMediaIds = saveUserMediaTypeForm.getTopMediaTypeIds();

        String subdivideMediaId = userMediaType.getSubdivideMediaTypeId();
        String topMediaId = userMediaType.getTopMediaTypeId();

        if (subMediaIds != null && subMediaIds.length > 0){
            String newTop = StringUtils.join(subMediaIds,",");
            if (!newTop.equals(topMediaId)) {
                return false;
            }
        }
        if (topMediaIds != null && topMediaIds.length > 0){
            String newSub = StringUtils.join(topMediaIds,",");
            if (!newSub.equals(subdivideMediaId)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public List<MediaType> searchByType(String type) {
        LambdaQueryWrapper<MediaType> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(MediaType::getType, type);
        lambdaQueryWrapper.eq(MediaType::getDelFlag,'0');
        lambdaQueryWrapper.orderByAsc(MediaType::getSort);
        return list(lambdaQueryWrapper);
    }

    @Override
    public List<UserMediaTypeDTO> getUserMediaType(String type, Integer brandId) {
        int userId = UserLoginContextHolder.get().getUserId();

        // 用户自定义的媒体分类（没有自定义取默认值）
        List<Integer> checkList = getCheckList(type, brandId, userId);

        //查询概览页要展示的所有分类
        LambdaQueryWrapper<MediaType> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.in(MediaType::getScope,Arrays.asList('1','2','3','4','5','6'));
        // 用户有权限的媒体分类
        Collection<Integer> permissionList = getpermissionList("top", brandId, userId);
        if (CollectionUtil.isNotEmpty(permissionList)) {
            lambdaQueryWrapper.in(MediaType::getId, permissionList);
        } else {
            return new ArrayList<>();
        }

//        if (type.equals("top")) {
//            lambdaQueryWrapper.in(MediaType::getScope,Arrays.asList('1','2','3'));
//        } else if(type.equals("subdivide")) {
//            lambdaQueryWrapper.in(MediaType::getScope,Arrays.asList('4','5','6'));
//        }

        lambdaQueryWrapper.eq(MediaType::getDelFlag, '0');
        lambdaQueryWrapper.orderByAsc(MediaType::getSort);
        List<MediaType> topMediaType =  list(lambdaQueryWrapper);

        Map<String,List<MediaType>> pTypeMap = topMediaType.stream()
                .filter(mediaType -> mediaType.getPid().equals(0))
                .collect(Collectors.groupingBy(MediaType::getType,LinkedHashMap::new,Collectors.toList()));

        Map<Integer,List<MediaType>> childMap = topMediaType.stream()
                .filter(mediaType -> !mediaType.getPid().equals(0))
                .collect(Collectors.groupingBy(MediaType::getPid,LinkedHashMap::new,Collectors.toList()));

        List<UserMediaTypeDTO> result = new ArrayList<>();
        for (String s : pTypeMap.keySet()) {
            UserMediaTypeDTO userMediaTypeDTO = new UserMediaTypeDTO();
            userMediaTypeDTO.setType(s);
            List<MediaType> values = pTypeMap.get(s);
            userMediaTypeDTO.setMediaTypeList(values);
            List<Integer> ids = values.stream().map(MediaType::getId).collect(Collectors.toList());
            while (ids.size()<3){
                ids.add(null);
            }

            List<String> names = values.stream().map(MediaType::getName).collect(Collectors.toList());
            while (names.size()<3){
                names.add(null);
            }
            userMediaTypeDTO.setId(StringUtils.join(ids,","));
            userMediaTypeDTO.setName(names);
            Boolean check = false;
            for (Integer id : ids) {
                if (checkList.contains(id)){
                    check = true;
                    break;
                }
            }
            userMediaTypeDTO.setCheck(check);

            //添加子分类
            List<MediaType> childList = new ArrayList<>();
            for (Integer id : ids) {
                List<MediaType> child = childMap.get(id);
                if (CollectionUtil.isNotEmpty(child)){
                    childList.addAll(child);
                }
            }
            if (CollectionUtil.isEmpty(childList)) {
                userMediaTypeDTO.setChild(new ArrayList<>());
            } else {
                userMediaTypeDTO.setChild(convert(userMediaTypeDTO,childList,checkList));
            }

            result.add(userMediaTypeDTO);
        }
        return result;
    }

    @NotNull
    public List<Integer> getCheckList(String type, Integer barandId, int userId) {
        List<Integer> checkList = new ArrayList<>();
        //查询自选分类
        LambdaQueryWrapper<UserMediaType> userMediaTypeWrapper = new LambdaQueryWrapper<>();
        userMediaTypeWrapper.eq(UserMediaType::getUserId, userId);
        userMediaTypeWrapper.eq(UserMediaType::getBrandId, barandId);
        userMediaTypeWrapper.eq(UserMediaType::getDelFlag, '0');
        List<UserMediaType> list = userMediaTypeService.list(userMediaTypeWrapper);
        if (CollectionUtil.isEmpty(list)) {
            LambdaQueryWrapper<UserMediaType> userMediaTypeWrapperDefault = new LambdaQueryWrapper<>();
            userMediaTypeWrapperDefault.eq(UserMediaType::getUserId, 0);
            userMediaTypeWrapperDefault.eq(UserMediaType::getBrandId, 0);
            userMediaTypeWrapperDefault.eq(UserMediaType::getDelFlag, '0');
            list = userMediaTypeService.list(userMediaTypeWrapperDefault);
        }
        UserMediaType userMediaType = list.get(0);
        String topStr = userMediaType.getTopMediaTypeId();
        String subStr = userMediaType.getSubdivideMediaTypeId();

        checkList = Arrays.asList(topStr.split(","))
                .stream().filter(v -> StringUtils.isNotBlank(v))
                .map(Integer::parseInt).collect(Collectors.toList());

        if (StringUtils.isNotBlank(subStr)) {
            List<Integer> subdivide = Arrays.asList(subStr.split(","))
                    .stream().filter(v -> StringUtils.isNotBlank(v))
                    .map(Integer::parseInt).collect(Collectors.toList());
            checkList.addAll(subdivide);
        }

        //加上权限校验
        String permissionMediaType = userMediaType.getPermissionMediaType();
        List<Integer> permissionMediaTypes = new ArrayList<>();
        if (StringUtils.isNotBlank(permissionMediaType)) {
            permissionMediaTypes = Arrays.asList(permissionMediaType.split(","))
                    .stream().filter(v -> StringUtils.isNotBlank(v))
                    .map(Integer::parseInt).collect(Collectors.toList());
        }
        if (CollectionUtil.isNotEmpty(permissionMediaTypes)) {
            Collection<Integer> intersection = CollectionUtil.intersection(checkList, permissionMediaTypes);
            checkList = new ArrayList<>(intersection);
        }

        return checkList;
    }

    /**
     * 获取有权限的媒体分类
     * @param type
     * @param barandId
     * @param userId
     * @return
     */
    public Collection<Integer> getpermissionList(String type, Integer barandId, int userId) {
        //查询自选分类
        LambdaQueryWrapper<UserMediaType> userMediaTypeWrapper = new LambdaQueryWrapper<>();
        userMediaTypeWrapper.eq(UserMediaType::getUserId, userId);
        userMediaTypeWrapper.eq(UserMediaType::getBrandId, barandId);
        userMediaTypeWrapper.eq(UserMediaType::getDelFlag, '0');
        List<UserMediaType> list = userMediaTypeService.list(userMediaTypeWrapper);
        if (CollectionUtil.isEmpty(list)) {
            LambdaQueryWrapper<UserMediaType> userMediaTypeWrapperDefault = new LambdaQueryWrapper<>();
            userMediaTypeWrapperDefault.eq(UserMediaType::getUserId, 0);
            userMediaTypeWrapperDefault.eq(UserMediaType::getBrandId, 0);
            userMediaTypeWrapperDefault.eq(UserMediaType::getDelFlag, '0');
            list = userMediaTypeService.list(userMediaTypeWrapperDefault);
        }
        UserMediaType userMediaType = list.get(0);
        String permissionMediaType;
        if (type.equals("top")) {
            permissionMediaType = userMediaType.getPermissionMediaType();
        } else {
            permissionMediaType = userMediaType.getPermissionMediaTypeDalei();
        }

        List<Integer> permissionMediaTypes = new ArrayList<>();
        if (StringUtils.isNotBlank(permissionMediaType)) {
            permissionMediaTypes = Arrays.asList(permissionMediaType.split(","))
                    .stream().filter(v -> StringUtils.isNotBlank(v))
                    .map(Integer::parseInt).collect(Collectors.toList());
        }
        return permissionMediaTypes;
    }


    private List<UserMediaTypeDTO> convert(UserMediaTypeDTO userMediaTypeDTO,List<MediaType> childList, List<Integer> checkList){
        List<UserMediaTypeDTO> result = new ArrayList<>();
        List<Integer> pIds = Arrays.asList(userMediaTypeDTO.getId().split(","))
                .stream().filter(v -> StringUtils.isNotBlank(v))
                .map(Integer::parseInt).collect(Collectors.toList());
        // childList根据type分组转成map
        Map<String,List<MediaType>> childMap = childList.stream()
                .filter(mediaType -> !mediaType.getPid().equals(0))
                .collect(Collectors.groupingBy(MediaType::getType,LinkedHashMap::new,Collectors.toList()));
        // 循环childMap，有多少不同的type，userMediaTypeDTO就有多少个child
        Set<String> types = childMap.keySet();
        for (String type : types) {
            UserMediaTypeDTO newType = new UserMediaTypeDTO();
            newType.setType(type);
            List<MediaType> mediaTypes = childMap.get(type);
            newType.setMediaTypeList(mediaTypes);
            List<Integer> ids = mediaTypes.stream().map(MediaType::getId).collect(Collectors.toList());
            newType.setId(StringUtils.join(ids, ","));
            List<String> names = mediaTypes.stream().map(MediaType::getName).collect(Collectors.toList());
            newType.setName(names);
            Boolean check = false;
            for (Integer id : ids) {
                if (checkList.contains(id)){
                    check = true;
                    break;
                }
            }
            newType.setCheck(check);
            result.add(newType);
        }

//        for (Integer pid : pIds) {
//            UserMediaTypeDTO newType = new UserMediaTypeDTO();
//            List<Integer> ids = childList.stream().filter(mediaType -> pid.equals(mediaType.getPid())).map(MediaType::getId).collect(Collectors.toList());
//            newType.setId(StringUtils.join(ids, ","));
//            newType.setName(childList.stream().filter(mediaType -> pid.equals(mediaType.getPid())).map(MediaType::getName).collect(Collectors.toList()));
//            Boolean check = false;
//            for (Integer id : ids) {
//                if (checkList.contains(id)){
//                    check = true;
//                    break;
//                }
//            }
//            newType.setCheck(check);
//            result.add(newType);
//        }
        return  result;
    }

}




